<?php
/********************************************************************
 *	Author:
 *		Jestery Liu <jestery@gmail.com>
 *		http://www.pte.cn
 *
 *	File:			Image.class.php
 *	Create Date:	2007-02-15 15:09:56 CST
 *******************************************************************/

require_once(PTE::getCoreLibsPath().'FileSpec.class.php');

class Image extends FileSpec
{
	private $scale = true;
	private $thumb = false;
	private $thumbMaxWidth;
	private $thumbMaxHeight;
	private $thumbPath;
	private $thumbFile;
	private $thumbDest;
	private $thumbWidth;
	private $thumbHeight;
	private $imageType;
	private $supportedTypes;
	private $width;
	private $height;
	private $srcRes;
	private $destRes;
	private $outputFunction;

	/**
	 * 构造函数
	 *
	 * @param string $filename 要操作的文件的全路径
	 * @return Image|false
	 */
	public function __construct($filename)
	{
		$imageInfo = @getimagesize($filename);
		if ($imageInfo===false)
			return false;
		$this->filename = $filename;
		list($this->width, $this->height, $this->imageType) = $imageInfo;
		$this->supportedTypes = imagetypes();
		switch ($this->imageType)
		{
		case IMAGETYPE_GIF:
			if (!($this->supportedTypes & IMG_GIF))
				return false;
			$this->srcRes = imagecreatefromgif($this->filename);
			$this->outputFunction = 'imagegif';
			break;
		case IMAGETYPE_JPEG:
			if (!($this->supportedTypes & IMG_JPG))
				return false;
			$this->srcRes = imagecreatefromjpeg($this->filename);
			$this->outputFunction = 'imagejpeg';
			break;
		case IMAGETYPE_PNG:
			if (!($this->supportedTypes & IMG_PNG))
				return false;
			$this->srcRes = imagecreatefrompng($this->filename);
			$this->outputFunction = 'imagepng';
			break;
		case IMAGETYPE_WBMP:
			if (!($this->supportedTypes & IMG_WBMP))
				return false;
			$this->srcRes = imagecreatefromwbmp($this->filename);
			$this->outputFunction = 'imagewbmp';
			break;
		case IMAGETYPE_XBM:
			$this->srcRes = imagecreatefromxbm($this->filename);
			$this->outputFunction = 'imagexbm';
			break;
		default:
			throw new ImageException('Unsupported image type.', -1);
		}
		parent::__construct($filename);
	}

	/**
	 * 设置是否按比例缩放
	 *
	 * @param bool $bool
	 */
	public function setScale($bool) { $this->scale = $bool; }
	/**
	 * 取得图片宽度
	 *
	 * @return integer 宽度值（像素）
	 * @access public
	 */
	public function getWidth() {return $this->width;}
	/**
	 * 取得图片高度
	 *
	 * @return integer 高度值（像素）
	 * @access public
	 */
	public function getHeight() {return $this->height;}
	/**
	 * 设置缩略图的最大宽度。
	 *
	 * @param integer $w 宽度值（像素）
	 * @access public
	 */
	public function setThumbMaxWidth($w) { $this->thumbMaxWidth = $w; }
	/**
	 * 设置缩略图最大高度。
	 *
	 * @param integer $h 高度值（像素）
	 * @access public
	 */
	public function setThumbMaxHeight($h) { $this->thumbMaxHeight = $h; }
	/**
	 * 设置缩略图保存路径
	 *
	 * @param string $p 路径
	 * @access public
	 */
	public function setThumbPath($p) { $this->thumbPath = PTE::normalizePath($p); }
	/**
	 * 设置缩略图保存的文件名
	 *
	 * @param string $filename 文件名
	 * @param string $useOrigExtension 如果为true，则自动在文件名后面加上源文件的扩展名，否则直接使用文件名。
	 * @access public
	 */
	public function setThumbFile($filename, $useOrigExtension = true)
	{
		if ($useOrigExtension)
			$this->thumbFile = $filename.$this->extension;
		else
			$this->thumbFile = $filename;
	}
	
	public function setThumb($flag) {
		$this->thumb = $flag;
	}
	/**
	 * 保存缩略图
	 *
	 * @return 如果成功则返回保存的地址，否则返回false
	 */
	public function saveThumb()
	{
		if (empty($this->thumbPath) || empty($this->thumbFile))
			throw new ImageException("thumbPath and/or thumbFile doesn't set.", E_USER_ERROR);
		if (!$this->thumb)
		{
			if (!$this->createThumb())
				return false;
		}
		$this->thumbDest = $this->thumbPath.$this->thumbFile;
		$o = $this->outputFunction;
		if ($o($this->destRes, $this->thumbDest))
			return $this->thumbDest;
		else
			return false;
	}

	private function createThumb()
	{
		$this->calcThumbSize();
		$this->destRes = imagecreatetruecolor($this->thumbWidth, $this->thumbHeight);
		$c = imagecolorallocate($this->destRes, 255,255,255);
		imagefilledrectangle($this->destRes, 0,0,$this->thumbWidth, $this->thumbHeight, $c);
		if (imagecopyresampled($this->destRes, $this->srcRes, 0,0,0,0,$this->thumbWidth, $this->thumbHeight, $this->width, $this->height))
		{
			$this->thumb=true;
			return true;
		}
		else
		{
			$this->thumb=false;
			return false;
		}
	}

	private function calcThumbSize()
	{
		if ($this->thumbMaxWidth<1 || $this->thumbMaxHeight<1)
			throw new ImageException("thumbMaxWidth and/or thumbMaxHeight doesn't set.", E_USER_ERROR);
		if (!$this->scale)
		{
			$this->thumbWidth = $this->thumbMaxWidth;
			$this->thumbHeight = $this->thumbMaxHeight;
			return true;
		}
		$srcScale = $this->width / $this->height;
		$thumbScale = $this->thumbMaxWidth /  $this->thumbMaxHeight;
		if ($srcScale > $thumbScale)
		{
			$this->thumbWidth = $this->thumbMaxWidth;
			$this->thumbHeight = floor($this->thumbMaxWidth / $this->width * $this->height);
		}
		else
		{
			$this->thumbHeight = $this->thumbMaxHeight;
			$this->thumbWidth = floor($this->thumbMaxHeight / $this->height * $this->width);
		}
		return true;
	}
}

class ImageException extends Exception {
	public function __construct($message, $code=0) {
		parent::__construct($message, $code);
	}
}

/* vim: set ts=4 sw=4 ff=unix: */
